package com.bosssoft.boss_exam_web.Controller;


import com.bosssoft.boss_exam_core.enums.ResultCode;
import com.bosssoft.boss_exam_core.enums.business.DepartmentEnum;
import com.bosssoft.boss_exam_core.exception.*;
import com.bosssoft.boss_exam_core.util.web.ResponseUtil;
import com.bosssoft.boss_exam_core.validator.Order;
import com.bosssoft.boss_exam_core.validator.Sort;
import com.bosssoft.boss_exam_db.entity.Admin;
import com.bosssoft.boss_exam_db.entity.Company;
import com.bosssoft.boss_exam_db.entity.Department;
import com.bosssoft.boss_exam_db.model.vo.CascaderVO;
import com.bosssoft.boss_exam_db.service.busines.AdminService;
import com.bosssoft.boss_exam_db.service.busines.DepartmentService;
import com.bosssoft.boss_exam_web.common.annotation.LoginAdmin;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotNull;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/admin/department")
@Validated
@Slf4j
@Api(value="部门控制器")
public class DepartmentController {

    //注入部门服务
    @Autowired
    private DepartmentService departmentService;

    //注入管理员服务
    @Autowired
    private AdminService adminService;

    @ApiOperation(value="部门查询", notes="可根据部门名称查询部门" ,httpMethod="GET",response = Object.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name="deparmentId", value="部门ID", dataType = "String", required=false, dataTypeClass=String.class),
            @ApiImplicitParam(name="parentId", value="父部门ID", dataType = "String", required=false, dataTypeClass=String.class),
            @ApiImplicitParam(name="leaderName", value="部门负责人名称", dataType = "String", required=false, dataTypeClass=String.class),
            @ApiImplicitParam(name="page", value="当前页码", dataType = "String", required=false, dataTypeClass=Integer.class),
            @ApiImplicitParam(name="limit", value="每页显示条数", dataType = "String", required=false, dataTypeClass=Integer.class),
            @ApiImplicitParam(name="sort", value="排序依据", dataType = "String", required=false, dataTypeClass=String.class),
            @ApiImplicitParam(name="order", value="排序方式", dataType = "String", required=false, dataTypeClass=String.class)
    })
    @GetMapping("/list")
    public Object list(@LoginAdmin String adminId,
                       @RequestParam String deparmentId,
                       @RequestParam String parentId,
                       @RequestParam String leaderName,
                       @RequestParam(defaultValue = "1") Integer page,
                       @RequestParam(defaultValue = "10") Integer limit,
                       @Sort @RequestParam(defaultValue = "add_time") String sort,
                       @Order @RequestParam(defaultValue = "desc") String order) {
        if ( adminId == null) {
            return ResponseUtil.unlogin();
        }
        //查询当前用户所在公司
        Company company=adminService.selectAdminBelongCompany(adminId);
        PageInfo<Department> departmentDTOPageInfo = departmentService.queryByCondition(company,deparmentId,parentId,leaderName,page,limit, sort, order);
        if(departmentDTOPageInfo==null){
            log.error("【业余错误】，查询pageInfo为空");
            throw new QueryDataException();
        }else {
            Map<String, Object> data = new HashMap<>();
            data.put("total", departmentDTOPageInfo.getTotal());
            data.put("items", departmentDTOPageInfo.getList());
            return ResponseUtil.ok(data);
        }
    }

    @ApiOperation(value="部门添加", notes="添加部门" ,httpMethod="POST",response = Object.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name="department", value="部门对象json", dataType = "Department", required=true, dataTypeClass= Department.class),
    })
    @PostMapping("/create")
    public Object create(@LoginAdmin String adminId, @RequestBody Department department) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }
        Company company=adminService.selectAdminBelongCompany(adminId);
        if(company==null){
            log.error("【严重警告】该管理员没有公司");
            throw new BusinessException("该管理员，没有归属公司");
        }
        department.setCompanyId(company.getId());
        int recordNum = departmentService.saveNotNull(department);
        if(recordNum==1){
            return ResponseUtil.ok(department);
        }else{
            log.error("【系统错误】 保存部门失败");
            throw  new UpdateEntityException();
        }
    }

    @ApiOperation(value="部门详细信息查询", notes="可根据部门的ID查询详情" ,httpMethod="GET",response = Object.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name="id", value="部门ID，非空", dataType = "String", required=true, dataTypeClass=String.class),
    })
    @GetMapping("/read")
    public Object read(@LoginAdmin String  adminId, @NotNull Integer id) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }
        Department department = null;
        try {
            department = departmentService.selectByKey(id);
        }  catch (NoSuchMethodException | InvocationTargetException |IllegalAccessException e) {
            log.error("【系统错误】 反射操作异常"+e);
            throw  new ReflectionException(ResultCode.SYSTEM_INNER_ERROR);
        }catch (Exception e){
            log.error("【业务错误】 读取实体异常"+e);
            throw  new QueryDataException();
        }
        return ResponseUtil.ok(department);
    }


    @ApiOperation(value="部门更新", notes="更新部门" ,httpMethod="POST",response = Object.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name="department", value="部门对象json，必须携带部门ID", dataType = "Department", required=true, dataTypeClass= Department.class),
    })
    @PostMapping("/update")
    public Object update(@LoginAdmin String  adminId, @RequestBody Department department) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }
        int recordNum = departmentService.updateNotNull(department);
        if(recordNum==1){
            return ResponseUtil.ok(department);
        }else{
            log.error("【系统错误】 保存部门失败");
            throw  new UpdateEntityException();
        }
    }

    @ApiOperation(value="部门删除", notes="可根据部门的ID逻辑删除部门" ,httpMethod="POST",response = Object.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name="id", value="部门ID，非空", dataType = "String", required=true, dataTypeClass=String.class),
    })
    @PostMapping("/delete")
    public Object delete(@LoginAdmin String adminId, @RequestParam String id) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }
        Department department = new Department();
        department.setId(id);
        try {
            int i = departmentService.deleteForLogic(department);
        } catch (NoSuchMethodException|IllegalAccessException|InvocationTargetException e) {
            log.error("【系统错误】 反射操作异常"+e);
            throw  new ReflectionException(ResultCode.SYSTEM_INNER_ERROR);
        }catch (Exception e) {
            log.info("【业务错误】 逻辑删除部门异常"+e);
            throw  new DeleteEntityException();

        }
        return ResponseUtil.ok();
    }

    @ApiOperation(value="查询", notes="查询当前用户所在公司开设的所有部门" ,httpMethod="GET",response = Object.class)
    @GetMapping("/deparments")
    public Object getDeparmentByCompany(@LoginAdmin String adminId){
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }
        Company company=adminService.selectAdminBelongCompany(adminId);
        if(company==null){
            log.error("【严重警告】该管理员没有公司");
            throw new BusinessException("该管理员，没有归属公司");
        }
        List<CascaderVO> departmentList= departmentService.queryByCompany(company.getId(), DepartmentEnum.TOP_DEPARTMENT.getKey());
        return ResponseUtil.ok(departmentList);
    }


    @ApiOperation(value="查询所有管理员", notes="可根据部门的ID查询部门下的所有员工" ,httpMethod="POST",response = Object.class)
    @ApiImplicitParams({
            @ApiImplicitParam(name="id", value="部门ID", dataType = "String", required=true, dataTypeClass=String.class),
    })
    @PostMapping("/fetchAdmin")
    public Object fetchAdminByDepartment(@LoginAdmin String adminId, @RequestParam String id) {
        if (adminId == null) {
            return ResponseUtil.unlogin();
        }
        List<Admin> admins=this.adminService.queryAdminByDepartment(id);
        List<Admin> adminList = admins.stream().map(admin -> {
            admin.setPassword("");
            return admin;
        }).collect(Collectors.toList());
        return ResponseUtil.ok(adminList);
    }

}
